package org.asdtiang.exceldemo.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.Field;
import org.elasticsearch.search.sort.ScoreSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.asdtiang.exceldemo.domain.ArmyJob;

@Controller
@RequestMapping("/armyjob")
public class ArmyJobController {
	final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper

	@Autowired
	private ElasticsearchTemplate elasticsearchTemplate; // es工具

	@RequestMapping("/2019/{offset}/{size}/{query}")
	//@ResponseBody()
	public Object hello(@PathVariable String query, @PathVariable int offset, @PathVariable int size,Model model) {

		if(query==null||query.trim().equals("x")){
			query="*";
		}
		int pageNum = offset / size;
		Pageable pageable = PageRequest.of(pageNum, size, new Sort(Direction.DESC, "_score"));
		String preTag = "<font color='#dd4b39'>";// google color
		String postTag = "</font>";

		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.preTags(preTag);
		highlightBuilder.postTags(postTag);
		String[] fieldArray = new String[] { "jobCode", "armyCode", "armyName", "jobType", "jobName", "jobDesc",
				"addNumber", "sourceType", "edu", "eduDegree", "major", "testMajor", "universityMajorRequired",
				"societyMajorRequired", "universityJobRequired", "societyJobRequired", "othersRequired", "location",
				"phone" };

		ScoreSortBuilder sortBuilder = new ScoreSortBuilder();
		sortBuilder.order(SortOrder.ASC);
		NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder().withTrackScores(true).withSort(sortBuilder)
				.withQuery(QueryBuilders.queryStringQuery(query)).withHighlightBuilder(highlightBuilder);

		for (String f : fieldArray) {
			highlightBuilder.field(f);
		}
		builder.withFields(fieldArray);
		HighlightBuilder.Field[] highF = new Field[fieldArray.length];
		highlightBuilder.fields().toArray(highF);

		builder.withHighlightFields(highF);
		SearchQuery searchQuery = builder.build();

		searchQuery.setPageable(pageable);
		searchQuery.addSort(new Sort(Direction.DESC, "_score"));
		// 高亮字段
		AggregatedPage<ArmyJob> result = elasticsearchTemplate.queryForPage(searchQuery, ArmyJob.class,
				new SearchResultMapper() {
					@Override
					public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
							Pageable pageable) {
						List<ArmyJob> chunk = new ArrayList<>();
						long totalHits = response.getHits().getTotalHits();
						float maxScore = response.getHits().getMaxScore();

						for (SearchHit searchHit : response.getHits()) {
							if (response.getHits().getHits().length <= 0) {
								return null;
							}
							Map<String, Object> fieldsResult = new HashMap<>();
							searchHit.getSourceAsMap().forEach((k, v) -> {
								fieldsResult.put(k, v);
							});
							searchHit.getHighlightFields().forEach((k, v) -> {
								String result = "";
								for (Text t : v.fragments()) {
									result = result + t.toString();
								}
								fieldsResult.put(k, result);
							});
							ArmyJob pojo = mapper.convertValue(fieldsResult, ArmyJob.class);
							if(pojo.getMajor()!=null&&!pojo.getMajor().startsWith("本科")){
								pojo.setMajor(pojo.getMajor().replaceAll("本科","<br>本科"));
							}
							chunk.add(pojo);
						}
						Collections.reverse(chunk);
						return new AggregatedPageImpl<T>((List<T>) chunk, pageable, totalHits,
								response.getAggregations(), response.getScrollId(), maxScore);
					}
				});
		if(result==null){

		}
		model.addAttribute("indexPage",pageable.getPageNumber());
		model.addAttribute("totalPage", result.getTotalPages());
		model.addAttribute("total", result.getTotalElements());
		model.addAttribute("pageSize", pageable.getPageSize());
		model.addAttribute("query", query);
		model.addAttribute("data", result.getContent());

		return "armjob";
	}
}